#!/bin/sh
# -* coding: UTF-8 *-

luf_kernel_name="2.6.24-gentoo-r8-install-usb"
luf_kernel_archive="/misc/gentoo/kernels/kernel-image-${luf_kernel_name}.tar.bz2"
luf_stagedir="/misc/gentoo/stages/i686/install"

luf_workdir="/var/tmp/installusb"
luf_device="/dev/sdb"

luf_boot_size= #"640"           # Boot partition in blocks (1 block 1024 bytes)
luf_boot_label="usb-boot"       #

luf_kernel2_name="2.6.24-gentoo-r4-amd"
luf_kernel2_archive="/misc/gentoo/kernels/kernel-image-${luf_kernel2_name}.tar.bz2"
luf_add_dirs=(
    "/misc/gentoo/livecd"
)

depend() {
    if [ -z "${squashfs_path}" -o ! -x "${squashfs_path}" ] ; then
        eerror "squashfs program not found"
        return 8
    fi
    if [ -z "${luf_device}" -o ! -b "${luf_device}" ] ; then
        eerror "invalid block device"
        return 8
    fi
    return 0
}

init_workdir() {
    local retval

    luf_init_workdir "$@" ; retval=$?
    [[ ${retval} -ne 0 ]] && return ${retval}

    return ${retval}
}

copy_stage() {
    local retval

    luf_copy_stage "$@" ; retval=$?
    [[ ${retval} -ne 0 ]] && return ${retval}

    rm -fr "${luf_workdir}"/source/misc/*

    #
    # Script make some actions in live filesystem
    #
    rm -f "${luf_workdir}"/source/etc/init.d/pg_autovacuum

    (
        echo ""
        echo "# !!! Disable update of /etc/inittab file"
        echo "livecd_fix_inittab() {"
        echo "    return 0"
        echo "}"
    ) >> "${luf_workdir}"/source/sbin/livecd-functions.sh

    ebegin  "Creating /etc/fstab and cleaning /etc/mtab"
    mkdir -p "${luf_workdir}"/source/etc

    (
        echo "/dev/loop0      /               squashfs        rw,defaults     0 0"
        echo "none            /proc           proc            defaults        0 0"
        echo "none            /dev/shm        tmpfs           defaults        0 0"
       #echo "none            /dev/pts        devpts          defaults        0 0"
    ) > "${luf_workdir}"/source/etc/fstab
    rm -f "${luf_workdir}"/source/etc/mtab

    #
    ebegin "Copying kernel to LiveUSB"
    mkdir -p "${luf_workdir}"/target/boot
    do_rsync --delete -a \
        "${luf_workdir}"/source/boot/kernel-genkernel-x86-${luf_kernel_name} \
        "${luf_workdir}"/source/boot/initramfs-genkernel-x86-${luf_kernel_name} \
        "${luf_workdir}"/target/boot/
    eend $?

    ebegin "Installing GRUB configuration file"
    do_rsync --delete -a "${luf_workdir}"/source/boot/grub "${luf_workdir}"/target/boot/
    rm -f "${luf_workdir}"/target/boot//grub/menu.lst
    touch "${luf_workdir}"/target/livecd

    (
        echo "default 0"
        echo "timeout 5"
        echo "#splashimage=(hd0,0)/boot/grub/splash.xpm.gz"
        echo ""
        echo "title=Boot LiveUSB"
        echo "root (hd0,0)"
        echo "kernel (hd0,0)/boot/kernel-genkernel-x86-${luf_kernel_name} root=/dev/ram0 init=/linuxrc looptype=squashfs loop=/image udev nodevfs cdroot"
        echo "initrd (hd0,0)/boot/initramfs-genkernel-x86-${luf_kernel_name}"
        echo ""
        echo "title=Boot LiveUSB (SATA+IDE)"
        echo "root (hd0,0)"
        echo "kernel (hd0,0)/boot/kernel-genkernel-x86-${luf_kernel_name} root=/dev/ram0 init=/linuxrc looptype=squashfs loop=/image udev nodevfs cdroot doide"
        echo "initrd (hd0,0)/boot/initramfs-genkernel-x86-${luf_kernel_name}"
        echo ""
        echo "title=Boot LiveUSB (No SATA)"
        echo "root (hd0,0)"
        echo "kernel (hd0,0)/boot/kernel-genkernel-x86-${luf_kernel_name} root=/dev/ram0 init=/linuxrc looptype=squashfs loop=/image udev nodevfs cdroot nosata doide"
        echo "initrd (hd0,0)/boot/initramfs-genkernel-x86-${luf_kernel_name}"
        echo "initrd (cd)/boot/initramfs-genkernel-x86-${luf_kernel_name}"
    ) > "${luf_workdir}"/target/boot/grub/menu.lst
    eend $?

    if [[ -e "${luf_kernel2_archive}" ]] ; then
        ebegin "Unpack alternative kernel ${luf_kernel2_name}"
        /usr/bin/tar -C "${luf_workdir}"/source -xjf ${luf_kernel2_archive} ; retval=$?
        eend ${retval}

        #
        ebegin "Copying alternative kernel to LiveUSB"
        do_rsync --delete -a \
            "${luf_workdir}"/source/boot/kernel-genkernel-x86-${luf_kernel2_name} \
            "${luf_workdir}"/source/boot/initramfs-genkernel-x86-${luf_kernel2_name} \
            "${luf_workdir}"/target/boot/
        eend $?

        ebegin "Adding alternative kernel to GRUB configuration file"

        (
            echo ""
            echo "title=Boot LiveUSB (alternative)"
            echo "root (cd)"
            echo "kernel (cd)/boot/kernel-genkernel-x86-${luf_kernel2_name} root=/dev/ram0 init=/linuxrc looptype=squashfs loop=/image udev nodevfs cdroot"
            echo "initrd (cd)/boot/initramfs-genkernel-x86-${luf_kernel2_name}"
        ) >> "${luf_workdir}"/target/boot/grub/menu.lst
        eend $?
    fi

    #
    mount_portages ; retval=$?
    [[ ${retval} -ne 0 ]] && return ${retval}

    do_in_chroot "in_chroot" "$@" ; retval=$?
    [[ ${retval} -ne 0 ]] && return ${retval}

    umount_portages ; retval=$?
    [[ ${retval} -ne 0 ]] && return ${retval}

    # Remove unneeded files
    rm -fr "${luf_workdir}"/source/usr/src/linux*
    rm -fr "${luf_workdir}"/source/var/cache/edb/*
    rm -fr "${luf_workdir}"/source/var/cache/genkernel
    rm -fr "${luf_workdir}"/source/var/tmp/ccache
    rm -fr "${luf_workdir}"/source/var/tmp/portage

    #
    rm -fr "${luf_workdir}"/source/var/db/pkg
    rm -fr "${luf_workdir}"/source/usr/share/doc

    #
    find "${luf_workdir}"/source/var/log -name "*log" -type f -exec rm -f {} \;
    find "${luf_workdir}"/source/var/run -name "*pid" -type f -exec rm -f {} \;

    #
    (
        echo "LC_MESSAGES=\"en_US.UTF-8\""
        echo "export LC_MESSAGES"
    ) > "${luf_workdir}"/source/etc/profile.d/lc_messages.sh
    chmod 0755 "${luf_workdir}"/source/etc/profile.d/lc_messages.sh

    return ${retval}
}

install_image() {
    local retval

    ebegin "Copying scripts to LiveUSB target directory"
    do_rsync --partial --archive /misc/gentoo/scripts "${luf_workdir}"/target/ ; retval=$?
    eend ${retval}
    [[ ${retval} -ne 0 ]] && return ${retval}

    ### Build squash
    ebegin "Build suashfs images"
    luf_build_squash_images "$@" ; retval=$?
    eend ${retval}
    [[ ${retval} -ne 0 ]] && return ${retval}
    return 0
}

install_media() {
    ### Make out USB-flash
    ebegin "Make out USB-flash drive ${luf_device}"
    eindent 1
    make_out_flash "$@" ; retval=$?
    eoutdent 1
    eend ${retval}
    [[ ${retval} -ne 0 ]] && return ${retval}

    ### Copy files to USB-flash
    ebegin "Copy files to USB-flash ${luf_device}"
    eindent 1
    copy_boot_to_usbflash "$@" ; retval=$?
    eoutdent 1
    eend ${retval}
    [[ ${retval} -ne 0 ]] && return ${retval}

    ### Install GRUB
    ebegin "Install GRUB to USB-flash ${luf_device}"
    eindent 1
    install_grub "$@" ; retval=$?
    eoutdent 1
    eend ${retval}
    return 0
}

in_chroot() {
    eindent 1
    einfo "Updating chroot"

    rc-update add syslog-ng default
    rc-update delete netmount
    rc-update delete modules

    # Add user
    userdel -r local
    useradd -m -G wheel,audio,plugdev local

    # Change users passwords
    echo "root:root" | chpasswd
    echo "local:local" | chpasswd

    depmod -a "${luf_kernel_name}"
    if [[ -e "${luf_kernel2_archive}" ]] ; then
        depmod -a "${luf_kernel2_name}"
    fi

    update-modules --force

    update-env

    eoutdent 1
    return 0
}

mount_portages() {
    ebegin "Mount portage tree"
    mount --bind /usr/portage "${luf_workdir}"/source/usr/portage
    eend $?

    if [ -d "${luf_workdir}"/source/usr/portage/packages ] ; then
        ebegin "Mount binary packages dir"
        mount --bind /misc/gentoo/packages/i686/desktop "${luf_workdir}"/source/usr/portage/packages
        eend $?
    fi

    if [ -d "${luf_workdir}"/source/usr/portage/distfiles ] ; then
        ebegin "Mount source files dir"
        mount --bind /misc/gentoo/distfiles "${luf_workdir}"/source/usr/portage/distfiles
        eend $?
    fi
}

umount_portages() {
    if [ -d "${luf_workdir}"/source/usr/portage/distfiles ] ; then
        if is_mount "${luf_workdir}"/source/usr/portage/distfiles ; then
            ebegin "Unmount source files dir"
            umount "${luf_workdir}"/source/usr/portage/distfiles
            eend $?
        fi
    fi

    if [ -d "${luf_workdir}"/source/usr/portage/packages ] ; then
        if is_mount "${luf_workdir}"/source/usr/portage/packages ; then
            ebegin "Unmount binary packages dir"
            umount "${luf_workdir}"/source/usr/portage/packages
            eend $?
        fi
    fi

    if is_mount "${luf_workdir}"/source/usr/portage ; then
        ebegin "Unmount portage tree dir"
        umount "${luf_workdir}"/source/usr/portage
        eend $?
    fi
}

copy_boot_to_usbflash() {
    local retval
    local add_dirs
    local retval1

    mkdir -p "${luf_workdir}"/mountpoint ; retval=$?
    if [ ${retval} -ne 0 ] ; then
        return ${retval}
    fi

    retval1=255
    ebegin "Copy boot content"
    mount "${luf_device}"1 "${luf_workdir}"/mountpoint ; retval=$?
    if [ ${retval} -eq 0 ] ; then
        do_rsync --delete --partial --archive "${luf_workdir}"/target/* "${luf_workdir}"/mountpoint ; retval1=$?

        if [[ -n "${luf_add_dirs}" ]] ; then
            local dir

            ebegin "Append additional directories to LiveUSB"
            eindent 1

            for dir in "${luf_add_dirs[@]}" ; do
                if [[ -d "${dir}" ]] ; then
                    einfo "Apending ${dir}"
                    do_rsync --delete --partial --archive "${dir}"/* "${luf_workdir}"/mountpoint ; retval1=$?
                    [ ${retval1} -ne 0 ] && break
                fi
            done
            eoutdent 1
            eend ${retval1}
        fi
        umount "${luf_workdir}"/mountpoint ; retval=$?
    fi

    [[ ${retval1} -ne 0 ]] && retval=${retval1}
    eend ${retval}

    rm -r "${luf_workdir}"/mountpoint
    return ${retval}
}
